#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windows.h>

#define MAX_NAME_LEN 50
#define MAX_PHONE_LEN 20
#define MAX_ADDR_LEN 100
#define FILENAME "contacts.txt"

typedef struct Contact {
    char name[MAX_NAME_LEN];
    char phone[MAX_PHONE_LEN];
    char address[MAX_ADDR_LEN];
    struct Contact *next;
} Contact;//用链表实现通讯录数据储存 

Contact *head = NULL;

// 函数声明
void displayMenu();//菜单 
void enterContact();//新增联系人 
void deleteContact();//删除联系人 
void listContacts();//展开联系人 
void searchContact();//搜索联系人 
void saveContacts();//保存联系人 
void loadContacts();//加载联系人 
void freeContacts();//释放内存并退出系统 

int main() {
    int choice;
    
    while (1) {
    	
        displayMenu();
        printf("请输入您的选择(1-7): ");
        scanf("%d", &choice);
        system("cls");
        getchar(); // 清除输入缓冲区
        
        switch (choice) {
            case 1:
                enterContact();
                system("cls");
                break;
            case 2:
                deleteContact();system("pause");
                system("cls");
                break;
            case 3:
                listContacts();
                system("pause");
                system("cls");
                break;
            case 4:
                searchContact();
                system("pause");
				system("cls");
                break;
            case 5:
                saveContacts();system("pause");
                system("cls");
                break;
            case 6:
                loadContacts();system("pause");
                system("cls");
                break;
            case 7:
                freeContacts();system("pause");
                system("cls");
                printf("感谢使用通讯录管理系统，再见！\n");
                exit(0);
            default:
                printf("无效的输入，请重新选择！\n");
        }
    }
    
    return 0;
}

void displayMenu() {
    printf("\n====== 通讯录管理系统 ======\n");
    printf("1. 添加联系人\n");
    printf("2. 删除联系人\n");
    printf("3. 显示所有联系人\n");
    printf("4. 查找联系人\n");
    printf("5. 保存联系人到文件\n");
    printf("6. 从文件加载联系人\n");
    printf("7. 退出系统\n");
    printf("============================\n");
}

void enterContact() {
    Contact *newContact = (Contact *)malloc(sizeof(Contact));
    if (newContact == NULL) {
        printf("内存分配失败！\n");
        return;
    }
    
    printf("\n请输入联系人姓名: ");
    fgets(newContact->name, MAX_NAME_LEN, stdin);
    newContact->name[strcspn(newContact->name, "\n")] = '\0'; // 移除换行符
    
    printf("请输入联系人电话: ");
    fgets(newContact->phone, MAX_PHONE_LEN, stdin);
    newContact->phone[strcspn(newContact->phone, "\n")] = '\0';
    
    printf("请输入联系人地址: ");
    fgets(newContact->address, MAX_ADDR_LEN, stdin);
    newContact->address[strcspn(newContact->address, "\n")] = '\0';
    
    // 添加到链表头部
    newContact->next = head;
    head = newContact;
    
    printf("联系人添加成功！\n");
}

void deleteContact() {
    if (head == NULL) {
        printf("通讯录为空，没有联系人可删除！\n");
        return;
    }
    
    char name[MAX_NAME_LEN];
    printf("\n请输入要删除的联系人姓名: ");
    fgets(name, MAX_NAME_LEN, stdin);
    name[strcspn(name, "\n")] = '\0';
    
    Contact *current = head;
    Contact *prev = NULL;
    bool found = false;
    
    while (current != NULL) {
        if (strcmp(current->name, name) == 0) {
            found = true;
            if (prev == NULL) {
                // 删除的是第一个节点
                head = current->next;
            } else {
                prev->next = current->next;
            }
            free(current);
            printf("联系人 %s 已删除！\n", name);
            break;
        }
        prev = current;
        current = current->next;
    }
    
    if (!found) {
        printf("未找到联系人 %s！\n", name);
    }
}

void listContacts() {
    if (head == NULL) {
        printf("通讯录为空！\n");
        return;
    }
    
    printf("\n====== 所有联系人 ======\n");
    Contact *current = head;
    int count = 1;
    
    while (current != NULL) {
        printf("%d. 姓名: %s\n", count, current->name);
        printf("   电话: %s\n", current->phone);
        printf("   地址: %s\n", current->address);
        printf("------------------------\n");
        current = current->next;
        count++;
    }
}

void searchContact() {
    if (head == NULL) {
        printf("通讯录为空！\n");
        return;
    }
    
    char name[MAX_NAME_LEN];
    printf("\n请输入要查找的联系人姓名: ");
    fgets(name, MAX_NAME_LEN, stdin);
    name[strcspn(name, "\n")] = '\0';
    
    Contact *current = head;
    bool found = false;
    
    while (current != NULL) {
        if (strcmp(current->name, name) == 0) {
            found = true;
            printf("\n找到联系人:\n");
            printf("姓名: %s\n", current->name);
            printf("电话: %s\n", current->phone);
            printf("地址: %s\n", current->address);
            break;
        }
        current = current->next;
    }
    
    if (!found) {
        printf("未找到联系人 %s！\n", name);
    }
}

void saveContacts() {
    if (head == NULL) {
        printf("通讯录为空，没有数据可保存！\n");
        return;
    }
    
    FILE *file = fopen(FILENAME, "w");
    if (file == NULL) {
        printf("无法打开文件进行保存！\n");
        return;
    }
    
    Contact *current = head;
    while (current != NULL) {
        fprintf(file, "%s|%s|%s\n", current->name, current->phone, current->address);
        current = current->next;
    }
    
    fclose(file);
    printf("联系人已保存到文本文件 %s！\n", FILENAME);
}

void loadContacts() {
    FILE *file = fopen(FILENAME, "r");
    if (file == NULL) {
        printf("没有找到保存的联系人文件或文件为空。\n");
        return;
    }
    
    // 清空当前链表
    freeContacts();
    
    char line[MAX_NAME_LEN + MAX_PHONE_LEN + MAX_ADDR_LEN + 3]; // 包含分隔符和换行符
    Contact *prev = NULL;
    
    while (fgets(line, sizeof(line), file) != NULL) {
        // 移除换行符
        line[strcspn(line, "\n")] = '\0';
        
        Contact *newContact = (Contact *)malloc(sizeof(Contact));
        if (newContact == NULL) {
            printf("内存分配失败！\n");
            break;
        }
        
        // 使用strtok分割字符串
        char *token = strtok(line, "|");
        if (token != NULL) strncpy(newContact->name, token, MAX_NAME_LEN);
        
        token = strtok(NULL, "|");
        if (token != NULL) strncpy(newContact->phone, token, MAX_PHONE_LEN);
        
        token = strtok(NULL, "|");
        if (token != NULL) strncpy(newContact->address, token, MAX_ADDR_LEN);
        
        newContact->next = NULL;
        
        if (head == NULL) {
            head = newContact;
        } else {
            prev->next = newContact;
        }
        
        prev = newContact;
    }
    
    fclose(file);
    printf("联系人已从文本文件 %s 加载！\n", FILENAME);
}

void freeContacts() {
    Contact *current = head;
    while (current != NULL) {
        Contact *temp = current;
        current = current->next;
        free(temp);
    }
    head = NULL;
}
